#include "mboard.h"

#include <QMessageBox>

#include "mutil.h"

MBoard::MBoard(QWidget *parent) :
    QWidget(parent)
{
    build();

    panel->setOKEnabled(false);
    panel->setHintEnabled(false);
    panel->setUndoEnabled(false);

    connect(panel, SIGNAL(ok()), this, SLOT(advance()));
    connect(picker, SIGNAL(evilSelected(MGame::PlayerID)), this, SLOT(evilSelected(MGame::PlayerID)));
    connect(panel, SIGNAL(reset()), this, SLOT(reset()));
    newGame();
}

void MBoard::newGame()
{
    game = new MGame();
    connect(game, SIGNAL(gameOver(bool)), this, SLOT(gameOver(bool)));

    panel->setOKEnabled(true);
    viewer->getSeat(MGame::PREV)->reset();
    viewer->getSeat(MGame::YOU)->reset();
    viewer->getSeat(MGame::NEXT)->reset();
    picker->resetSelection();
    picker->updateBoxes(game);
    info->setText(MUtil::getStr("text_initcard"));
    viewer->update();
}

void MBoard::gameOver(bool win)
{
    disconnect(game, SIGNAL(gameOver(bool)), this, SLOT(gameOver(bool)));
    panel->setOKEnabled(false);
    int res = QMessageBox::information(this, MUtil::getStr("text_info"),
                                       MUtil::getStr(win ? "text_win" : "text_lose"),
                                       QMessageBox::Ok, QMessageBox::Cancel);
    if (res != QMessageBox::Ok)
        std::exit(0);
    delete game;
    newGame();
}

void MBoard::advance()
{
    if (game->getState() == MGame::TO_CHOOSE_YOUR_CARD)
    {
        QString s = game->setYourCards(picker->getSelected());
        if (s != "")
        {
            QMessageBox::warning(this, MUtil::getStr("text_info"), s);
            info->setText(s);
        }
        else
        {
            info->setText(MUtil::getStr("text_chooseevil"));
            panel->setOKEnabled(false);
            picker->resetSelection();
        }
    }
    else if (game->getState() == MGame::TO_CHOOSE_EVIL)
    {
        QString s = game->setEvilID(evil_p);
        if (s != "")
        {
            QMessageBox::warning(this, MUtil::getStr("text_info"), s);
            info->setText(s);
        }
        else
        {
            panel->setOKEnabled(true);
            info->setText(MUtil::getStr("text_evilcard"));
            viewer->getSeat(MGame::PREV)->setEvil(MGame::PREV == evil_p);
            viewer->getSeat(MGame::YOU)->setEvil(MGame::YOU == evil_p);
            viewer->getSeat(MGame::NEXT)->setEvil(MGame::NEXT == evil_p);
            viewer->update();
            picker->resetSelection();
        }
    }
    else if (game->getState() == MGame::TO_CHOOSE_EVIL_CARD)
    {
        QString s = game->setEvilExtraCards(picker->getSelected());
        if (s != "")
        {
            QMessageBox::warning(this, MUtil::getStr("text_info"), s);
            info->setText(s);
        }
        else
        {
            info->setText(MUtil::getStr("text_turncard").arg(MUtil::getStr(
                game->getTurn() == MGame::YOU ? "text_you" :
                game->getTurn() == game->EVILID ? "text_evil" :
                game->getTurn() == MGame::PREV ? "text_prev" : "text_next"
                                                 )));
            panel->setOKEnabled(true);
            picker->resetSelection();
            changeTurn();
        }
    }
    else if (game->getState() == MGame::TO_CHOOSE_TURN_CARD)
    {

        QString s = game->play(picker->getSelected());
        if (game->getState() == MGame::TO_CHOOSE_YOUR_CARD)
            return;
        if (s != "")
        {
            QMessageBox::warning(this, MUtil::getStr("text_info"), s);
            info->setText(s);
        }
        else
        {
            info->setText(MUtil::getStr("text_turncard").arg(MUtil::getStr(
                game->getTurn() == MGame::YOU ? "text_you" :
                game->getTurn() == game->EVILID ? "text_evil" :
                game->getTurn() == MGame::PREV ? "text_prev" : "text_next"
                                                 )));
            panel->setOKEnabled(true);
            picker->resetSelection();
            changeTurn();
        }
    }
    else
        return;
    picker->updateBoxes(game);

    if (game->getState() != MGame::TO_CHOOSE_YOUR_CARD)
    {
        viewer->getSeat(MGame::PREV)->updateCounter(game->getHandRemain(MGame::PREV));
        viewer->getSeat(MGame::YOU)->updateCounter(game->getHandRemain(MGame::YOU));
        viewer->getSeat(MGame::NEXT)->updateCounter(game->getHandRemain(MGame::NEXT));
    }
    viewer->update();
}

void MBoard::evilSelected(MGame::PlayerID p)
{
    evil_p = p;
    advance();
}

void MBoard::changeTurn()
{

    viewer->getSeat(MGame::PREV)->setCurrent(MGame::PREV == game->nowPlayer);
    viewer->getSeat(MGame::YOU)->setCurrent(MGame::YOU == game->nowPlayer);
    viewer->getSeat(MGame::NEXT)->setCurrent(MGame::NEXT == game->nowPlayer);
}

void MBoard::reset()
{
    if (game != NULL)
    {
        disconnect(game, SIGNAL(gameOver(bool)), this, SLOT(gameOver(bool)));
        panel->setOKEnabled(false);

        delete game;
    }
    newGame();
}

void MBoard::build()
{
    setLayout(new QVBoxLayout);
    layout()->setMargin(0);

    viewer = new MViewer;
    picker = new MPicker;
    up = new QGraphicsView(viewer);
    mid = new QGraphicsView(picker);
    picker->setParentWidget(mid);
    info = new QLabel(MUtil::getStr("text_help"));
    info->setAlignment(Qt::AlignCenter);

    panel = new MPanel;

    layout()->addWidget(up);
    layout()->addWidget(info);
    layout()->addWidget(mid);
    layout()->addWidget(panel);
}
